#ifndef XFFMPEG_H
#define XFFMPEG_H


#ifndef INT64_C
#define INT64_C
#define UINT64_C
#endif
#include <string>
#include <QMutex>
extern "C"
{
    #include <libavcodec\avcodec.h>
    #include <libavformat\avformat.h>
    #include <libswscale\swscale.h>
    #include <libswresample\swresample.h>
}

class XFFmpeg
{
public:
    static XFFmpeg *Get()
    {
        static XFFmpeg ff;
        return &ff;
    }
    /**打开视频文件，如果上次已经打开会先关闭
     * @para path 视频文件路径
     * return int return total ms
     */
    int Open(const char* path);
    void Close();

    /**
     * @brief Read
     * @return 返回值需要用户清理
     */
    AVPacket Read();

    int GetPTS(const AVPacket* pkt);

    /**
     * @brief Decode
     * @param pkt
     * @param yuv 如果为NULL，内部会重新生成一个AVFrame，否则会在原来基础上创建帧
     * @return
     */
    int Decode(const AVPacket &pkt);

    int GetVideoStream(){return m_videoStream;}
    int GetAudioStream(){return m_audioStream;}

    bool ToRGB(char* out, int outwidth, int outheight);

    int ToPCM(char *out);

    //pos 0~1
    bool Seek(float pos);

    std::string GetError();
    virtual ~XFFmpeg();

    int GetFPS(){return m_fps;}
    int GetPTS(){return m_pts;}
    int GetTotalMs(){return m_totalMs;}
    bool GetIsPlay(){return m_isPlay;}
    void SetIsPlay(bool isPlay){m_isPlay = isPlay;}
    int GetSampleRate(){return m_iSampleRate;}
    int GetSampleSize(){return m_iSampleSize;}
    int GetChannel(){return m_iChannel;}

protected:
    char m_szErrorbuf[128];
    QMutex m_mutex;
    AVFormatContext *m_ic; //保存打开之后的信息
    int m_totalMs;
    int m_fps;
    int m_pts;
    int m_videoStream;
    int m_audioStream;
    int m_iSampleRate;
    int m_iSampleSize;
    int m_iChannel;
    bool m_isPlay;
    SwsContext* m_cCtx;
    SwrContext *m_aCtx;
    AVFrame* m_yuv;
    AVFrame* m_pcm;
    XFFmpeg();
};

#endif // XFFMPEG_H
